package wassalt.Services;

import static wassalt.Utils.AppConstants.HTTP_STATUS;

import java.io.IOException;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;

import com.google.android.c2dm.C2DMessaging;

import wassalt.Utils.AppConstants;
import wassalt.Utils.User;
import wassalt.Utils.Util;
import wassalt.client.R;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

public class RegistrationService extends Service {

	@Override
	public void onStart(Intent intent, int startId) {
		Log.d(TAG, "start Service");
		// set the filters for the receiver and start it.
		IntentFilter filter = new IntentFilter();
		filter.addAction(AppConstants.C2DM_RESPONSE_FILTER);
		filter.addAction(AppConstants.REGISTRATION_RESPONSE_FILTER);
		registerReceiver(receiver, filter);
		// fire intent to http service
		Intent regServiceIntent = new Intent(this, HTTPService.class);
		regServiceIntent.setAction(AppConstants.REGISTRATION_RESPONSE_FILTER);
		regServiceIntent.putExtras(intent);
		startService(regServiceIntent);

		super.onStart(intent, startId);
	}

	/**
	 * Cookie name for authorization.
	 */
	private static final String AUTH_COOKIE_NAME = "SACSID";
	private static final String TAG = RegistrationService.class.getName();
	private Context mContext = this;

	/**
	 * Broadcast receiver to receive the results intents of registration from
	 * http service
	 */
	private BroadcastReceiver receiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context arg0, Intent resInetent) {
			try {
				Log.d("IntentReceived", resInetent.getAction());
				String action = resInetent.getAction();
				int http_status = resInetent.getExtras().getInt(HTTP_STATUS);
				Log.e(TAG, http_status + "");
				// check received intent http status
				if (http_status != HttpStatus.SC_OK) {
					((RegistrationService) mContext).SendUpdateUI(false);
					return;
				}

				String responseStr = resInetent.getExtras().getString(
						AppConstants.HTTP_RESPONSE);
				Log.d("res", responseStr);
				// get the response
				JSONObject responseObj = new JSONObject(responseStr);

				if (action.equals(AppConstants.REGISTRATION_RESPONSE_FILTER)) {
					if (!responseObj.isNull(AppConstants.SERVER_STATUS)
							&& responseObj
									.getString(AppConstants.SERVER_STATUS)
									.equals(AppConstants.SERVER_FAIL)) {
						Log.e("registeration Reply", "ehneh");
						throw new Exception(
								responseObj
										.getString(AppConstants.SERVER_STATUS));

					}

					// Success reply was received so send user data to be saved
					User.saveUser(RegistrationService.this, responseObj);
					// Try to load data to make sure nothing wrong
					User s = User.loadUser(RegistrationService.this);
					// register the user to C2DM
					registerC2DM(s.getMail());

				} else if (action.equals(AppConstants.C2DM_RESPONSE_FILTER)) {
					// update the UI according to C2DM registration on server
					// status
					if (responseObj.getString(AppConstants.SERVER_STATUS)
							.equals(AppConstants.SERVER_SUCC)) {
						Log.e("Registration", "response c2dm success");
						User.setRegistered(mContext);
						((RegistrationService) mContext).SendUpdateUI(true);
					} else {
						Log.e("Registration", "Fail c2dm fail");
						((RegistrationService) mContext).SendUpdateUI(false);
					}

				}

			} catch (Exception e) {
				// TODO Auto-generated catch block

				Log.e("Registration Exception", e.getMessage());
				((RegistrationService) mContext).SendUpdateUI(false);
			}
		}
	};

	/**
	 * @param accountName
	 *            the account user want to register to C2DM with
	 */
	private void registerC2DM(final String accountName) {
		Log.e("c2dmReg", "c2dm called");
		// Store the account name in shared preferences
		final SharedPreferences prefs = mContext.getSharedPreferences(
				AppConstants.SHARED_PREFS, Context.MODE_WORLD_WRITEABLE);
		SharedPreferences.Editor editor = prefs.edit();
		editor.putString(AppConstants.ACCOUNT_NAME, accountName);
		editor.remove(AppConstants.DEVICE_REG_KEY);
		editor.commit();
		C2DMessaging.register(mContext, AppConstants.SENDER_ID);
		Log.e("c2dmReg", "Done calling reg waiting reply");
	}

	/**
	 * Sends intent to the UI to update in case of registration activity is open
	 * 
	 * @param result
	 *            boolean The desire publish status whether it is success or not
	 */
	private void SendUpdateUI(boolean result) {
		Util.setDisconnecting(mContext, AppConstants.REG_CON_KEY, result+"");
		Intent broadCastIntent = new Intent(
				AppConstants.REGISTRATION_UI_UPDATE_FILTER);
		// Add the http status to the intent
		if (result)
			broadCastIntent.putExtra(HTTP_STATUS, HttpStatus.SC_OK);
		else
			broadCastIntent.putExtra(HTTP_STATUS, HttpStatus.SC_NOT_FOUND);

		sendBroadcast(broadCastIntent);
		Log.d(TAG, "RegDone_Sent_TO_UI");
		this.stopSelf();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Service#onDestroy() over written to unregister the
	 * broadcast receiver
	 */
	@Override
	public void onDestroy() {
		Log.d(TAG, "Destroy Service");
		// un-register the service
		unregisterReceiver(receiver);
		super.onDestroy();
	}

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}

}
